using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Blople.ManagerClasses;
using Blople.GameComponents;


namespace Blople.GameScenes
{
    public class ActionScene : GameScene
    {
        protected Rectangle screenBounds;

        protected Texture2D backgroundTexture;
        protected Texture2D pauseScreenTexture;
        protected Texture2D lineTexture;
        protected Texture2D blopTexture;
        protected Texture2D pointerTexture;

        protected BlopManager blopManager;

        protected Blop blop;
        protected Pointer pointer;

        protected SpriteFont mediumFont;

        protected ScoreField scoreField;

        protected KeyboardState oldKeyboardState;

        protected Song ingameSong;

        protected Boolean paused;
        protected Boolean gameOver;

        protected RumblePad rumblePad;

        protected int level;

        public ActionScene(Game game, Texture2D backgroundTexture, Texture2D pauseScreenTexture, Texture2D lineTexture, Texture2D blopTexture, Texture2D pointerTexture, Song ingameSong, SpriteFont mediumFont) : base(game)
        {
            screenBounds = new Rectangle(0, 0, Game.Window.ClientBounds.Width, Game.Window.ClientBounds.Height);

            this.backgroundTexture = backgroundTexture;
            this.pauseScreenTexture = pauseScreenTexture;
            this.lineTexture = lineTexture;
            this.blopTexture = blopTexture;
            this.pointerTexture = pointerTexture;
            this.ingameSong = ingameSong;

            this.mediumFont = mediumFont;

            pointer = new Pointer(game, pointerTexture);
            components.Add(pointer);

            blopManager = new BlopManager(game, blopTexture);
            blop = blopManager.CreateBlop(level);
            components.Add(blopManager);

            scoreField = new ScoreField(game, mediumFont);
            components.Add(scoreField);

            rumblePad = new RumblePad(game);
            components.Add(rumblePad);    
        }

        public override void Initialize()
        {
            
            base.Initialize();
        }

        public override void Update(GameTime gameTime)
        {
            KeyboardState keyboardState = Keyboard.GetState();
            bool pKey = (oldKeyboardState.IsKeyDown(Keys.P) && (keyboardState.IsKeyUp(Keys.P)));
            oldKeyboardState = keyboardState;

            if (pKey)
            {
                paused = !paused;
            }

            if ((!paused) && (!gameOver))
            {
                CollissionDetection();
                base.Update(gameTime);
            }
        }

        public override void Draw(GameTime gameTime)
        {
            SpriteBatch sBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
            sBatch.Draw(backgroundTexture, new Vector2(0, 0), Color.White);
            sBatch.Draw(lineTexture, new Vector2(0, 495), Color.White);
            base.Draw(gameTime);
            if (paused) {
                sBatch.Draw(pauseScreenTexture, new Vector2(0, 0), Color.White);
                sBatch.DrawString(mediumFont, "Paused", new Vector2((Game.Window.ClientBounds.Width - mediumFont.MeasureString("Paused").X) / 2, (Game.Window.ClientBounds.Height - mediumFont.MeasureString("Paused").Y) / 2), Color.White);
            }
        }

        public override void Show()
        {
            MediaPlayer.Play(ingameSong);
            gameOver = false;
            paused = false;
            base.Show();
        }

        public void AimLeft(float identifier)
        {
            if (pointer.Direction >= -1.0f)
            {
                pointer.Direction -= 0.05f * identifier;
            }
        }

        public void AimRight(float identifier)
        {
            if (pointer.Direction <= 1.0f)
            {
                pointer.Direction += 0.05f * identifier;
            }
        }

        public void Shoot()
        {
            blop.ShootBlop(pointer.Direction);
        }

        protected void CollissionDetection()
        {
            Vector2 velocity = blop.Velocity;

            if (blop.Position.X < screenBounds.Left + 40)
            {
                velocity = new Vector2(Math.Abs(blop.Velocity.X), blop.Velocity.Y);
                blop.Velocity = velocity;
            }
            if (blop.Position.X > screenBounds.Right - 40)
            {
                velocity = new Vector2(-Math.Abs(blop.Velocity.X), blop.Velocity.Y);
                blop.Velocity = velocity;
            }

            if (blop.Position.Y < screenBounds.Top + 40)
            {
                blop.Velocity = new Vector2(0, 0);
                blop.SwitchStatus();
                blop = blopManager.CreateBlop(level);
            }

            if (blopManager.Blops.Count > 1)
            {
                for (int i = 0; i <= blopManager.Blops.Count - 2; i++)
                {
                    BoundingSphere blop1 = new BoundingSphere(new Vector3(blopManager.Blops[i].Position.X, blopManager.Blops[i].Position.Y, 0), 40);
                    BoundingSphere blop2 = new BoundingSphere(new Vector3(blop.Position.X, blop.Position.Y, 0), 40);
                    if (blop2.Intersects(blop1))
                    {
                        if (blopManager.Blops[i].getColor() == blop.getColor())
                        {
                            //if (blopManager.Blops[i].AdjacentBlop == null)
                            //{
                            //    blopManager.Blops[i].AdjacentBlop = blop;
                            //    blop.AdjacentBlop = blopManager.Blops[i];
                            //}
                            //else
                            //{
                            //    blopManager.DestroyBlop(blopManager.Blops[i].AdjacentBlop);
                            //    blopManager.DestroyBlop(blopManager.Blops[i]);
                            //    blopManager.DestroyBlop(blop);
                            //}
                            blopManager.DestroyBlop(blopManager.Blops[i]);
                            blopManager.DestroyBlop(blop);
                            scoreField.IncreaseScore(10);
                            rumblePad.Rumble(60, 0.5f, 0.5f);
                        }
                        blop.Velocity = new Vector2(0, 0);
                        BoundingSphere controleSphere;
                        for (int j = 1; j < 10; j++)
                        {
                            controleSphere = new BoundingSphere(new Vector3(j * 50, 500, 0), 5);
                            if (blop2.Intersects(controleSphere)) 
                            {
                                gameOver = true;
                                MediaPlayer.Stop();
                            }
                        }
                        blop.SwitchStatus();
                        blop = blopManager.CreateBlop(level);
                    }
                }
            }
        }

        public Boolean GameOver
        {
            get { return gameOver; }
            set { gameOver = value; }
        }

        public int Score
        {
            get { return scoreField.Score; }
        }

        public int Level
        {
            get { return level; }
            set { level = value; }
        }

    }
}
